/**
 * AplControleInterno.java
 *
 * Projeto: SGA-LEDS
 *
 * Rodrigo Soares Maia IFES - Instituto Federal do Espírito Santo - Campus Serra
 */
package controleInterno.cgt;

import controleInterno.cdp.CategoriaTipo;
import controleInterno.cdp.ClassificacaoColaborador;
import controleInterno.cdp.Colaborador;
import controleInterno.cdp.Prioridade;
import controleInterno.cdp.Projeto;
import controleInterno.cdp.StatusProjeto;
import controleInterno.cdp.TipoAtividade;
import controleInterno.cdp.TipoProjeto;
import controleInterno.cdp.Usuario;
import controleInterno.cgd.ColaboradorDAO;
import controleInterno.cgd.TipoAtividadeDAOJPA;
import controleInterno.cgd.UsuarioDAO;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import utilitario.utilitarioPersistencia.DAO;
import utilitario.utilitarioPersistencia.DAOFactory;
import utilitario.utilitarioPessoa.cdp.Endereco;
import utilitario.utilitarioPessoa.cdp.Pessoa;
import utilitario.utilitarioPessoa.cdp.Sexo;

public class AplControleInterno
{
    private DAO apDaoColaborador = DAOFactory.obterDAO(Colaborador.class);
    private DAO apDaoUsuario = DAOFactory.obterDAO(Usuario.class);
    private DAO apDaoProjeto = DAOFactory.obterDAO(Projeto.class);
    private DAO apDaoTipoAtividade = DAOFactory.obterDAO(TipoAtividade.class);
    private DAO apDaoCategoriaTipo = DAOFactory.obterDAO(CategoriaTipo.class);
    
    private static AplControleInterno instance = null;

    public static AplControleInterno getInstance()
    {
        if (instance == null)
        {
            instance = new AplControleInterno();
        }
        return instance;
    }

    public Colaborador salvarColaborador(ArrayList<Object> atributos)
    {
        Colaborador c = new Colaborador();
        
        
        //TODO passar por hashmap
        c.setNome((String) atributos.get(0));
        c.seteMail((String) atributos.get(1));
        c.setTelefone((String) atributos.get(2));
        c.setDataNascimento((Calendar) atributos.get(3));
        c.setCpf((String) atributos.get(4));
        c.setIdentidade((String) atributos.get(5));
        c.setSexo(Sexo.valueOf((String) atributos.get(6))); //TODO pode haver uma atribuicao errada se vier errado de cima
        c.setFoto((byte[]) atributos.get(7));

        c.setDataIngresso((Calendar) atributos.get(8));
        c.setObservacoes((String) atributos.get(9));
        c.setTipo(ClassificacaoColaborador.valueOf((String) atributos.get(10))); //TODO pode haver uma atribuicao errada se vier errado de cima

        c.setEndereco((Endereco) atributos.get(11));
        
        try
        {
            c = (Colaborador) apDaoColaborador.salvar(c);
        }
        catch (Exception ex)
        {
            Logger.getLogger(AplControleInterno.class.getName()).log(Level.SEVERE, null, ex);
        }

        return c;
    }
    
    public Colaborador salvarColaborador(Map atributos)
    {
        Colaborador c = new Colaborador();

        c.setNome((String) atributos.get("nome"));
        c.seteMail((String) atributos.get("email"));
        c.setTelefone((String) atributos.get("telefone"));
        //c.setDataNascimento((Calendar) atributos.get("dataNascimento"));
        //c.setCpf((String) atributos.get("cpf"));
        //c.setIdentidade((String) atributos.get("identidade"));
        //c.setSexo(Sexo.valueOf((String) atributos.get("sexo"))); //TODO pode haver uma atribuicao errada se vier errado de cima
        //c.setFoto((byte[]) atributos.get("foto"));

        c.setDataIngresso((Calendar) atributos.get("dataIngresso"));
        //c.setObservacoes((String) atributos.get("observacoes"));
        c.setTipo(ClassificacaoColaborador.valueOf((String) atributos.get("tipo"))); //TODO pode haver uma atribuicao errada se vier errado de cima

        //c.setEndereco((Endereco) atributos.get("endereco"));
        
        try
        {
            c = (Colaborador) apDaoColaborador.salvar(c);
        }
        catch (Exception ex)
        {
            Logger.getLogger(AplControleInterno.class.getName()).log(Level.SEVERE, null, ex);
        }

        return c;
    }

    public Colaborador alterarColaborador(Colaborador c)
    {
        try
        {
            return (Colaborador) apDaoColaborador.salvar(c);
        }
        catch (Exception ex)
        {
            Logger.getLogger(AplControleInterno.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;
    }

    public boolean apagarColaborador(Colaborador c)
    {
        try
        {
            //TODO fazer validacao antes
            apDaoColaborador.excluir(c);
        }
        catch (Exception ex)
        {
            Logger.getLogger(AplControleInterno.class.getName()).log(Level.SEVERE, null, ex);
        }

        return true;
    }

    public List<Colaborador> obterColaboradores()
    {
        try
        {
            return (List<Colaborador>) apDaoColaborador.obter(Colaborador.class);
        }
        catch (Exception ex)
        {
            Logger.getLogger(AplControleInterno.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;
    }
    
    public Colaborador obterColaborador(Pessoa p)
    {
        return (Colaborador) ((ColaboradorDAO) apDaoColaborador).obterColaborador(p);
    }
    
    public Usuario salvarUsuario(ArrayList<Object> atributos)
    {
        Usuario u = new Usuario();
        u.setNome((String) atributos.get(0));
        u.setSenha(Usuario.gerarHashCode((String) atributos.get(1)));
        //u.setPrivilegio(Privilegio.valueOf((String) atributos.get(2))); //TODO pode haver uma atribuicao errada se vier errado de cima
        u.setPessoa((Pessoa) atributos.get(3));
        try
        {
            apDaoUsuario.salvar(u);
        }
        catch (Exception ex)
        {
            Logger.getLogger(AplControleInterno.class.getName()).log(Level.SEVERE, null, ex);
        }

        return u;
    }
    
    public Usuario salvarUsuario(Map atributos)
    {
        Usuario u = new Usuario();
                
        u.setNome((String) atributos.get("nome"));
        u.setSenha(Usuario.gerarHashCode((String) atributos.get("senha")));
        u.setPrivilegioAdm((Boolean) atributos.get("privilegioAdm"));
        u.setPrivilegioAdm((Boolean) atributos.get("privilegioGerente"));
        u.setPessoa((Pessoa) atributos.get("pessoa"));
        try
        {
            apDaoUsuario.salvar(u);
        }
        catch (Exception ex)
        {
            Logger.getLogger(AplControleInterno.class.getName()).log(Level.SEVERE, null, ex);
        }

        return u;
    }

    public Usuario salvarUsuario(String nome, String senha, boolean privilegioAdm, boolean privilegioGer, Pessoa p)
    {
        Usuario u = new Usuario();
        u.setNome(nome);
        u.setSenha(Usuario.gerarHashCode(senha));
        u.setPrivilegioAdm(privilegioAdm);
        u.setPrivilegioGerLab(privilegioGer);
        u.setPessoa(p);
        try
        {
            apDaoUsuario.salvar(u);
        }
        catch (Exception ex)
        {
            Logger.getLogger(AplControleInterno.class.getName()).log(Level.SEVERE, null, ex);
        }

        return u;
    }

    public Usuario alterarUsuario(Usuario u)
    {
        try
        {
            apDaoUsuario.salvar(u);
        }
        catch (Exception ex)
        {
            Logger.getLogger(AplControleInterno.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return u;
    }
    
    public Usuario alterarSenhaUsuario(Usuario u, String novaSenha)
    {
        //criptografando, pois a senha vem sem criptografia
        u.setSenha(Usuario.gerarHashCode(novaSenha));
        
        try
        {
            apDaoUsuario.salvar(u);
        }
        catch (Exception ex)
        {
            Logger.getLogger(AplControleInterno.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return u;
    }

    public boolean apagarUsuario(Usuario u)
    {
        //if (u.getPrivilegio() != Privilegio.ADMINISTRADOR)
        //{
            try
            {
                apDaoUsuario.excluir(u);
            }
            catch (Exception ex)
            {
                Logger.getLogger(AplControleInterno.class.getName()).log(Level.SEVERE, null, ex);
            }
            return true;
        //}
        //else
       // {
        //    return false;
        //}
    }

    public List obterUsuarios()
    {
        try
        {
            return apDaoUsuario.obter(Usuario.class);
        }
        catch (Exception ex)
        {
            Logger.getLogger(AplControleInterno.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return null;
    }

    public Usuario validarUsuario(String nome, String senha)
    {
        List<Usuario> l = obterUsuarios();
        String senhaCrip = Usuario.gerarHashCode(senha);

        for (int i = 0; i < l.size(); i++)
        {
            if (l.get(i).getNome().toLowerCase().equals(nome.toLowerCase()) && l.get(i).getSenha().equals(senhaCrip))
            {
                return l.get(i);
            }
        }
        return null;
    }

    public Usuario obterUsuario(Pessoa p)
    {
        return ((UsuarioDAO) apDaoUsuario).obterUsuario(p);
    }
    
    //PROJETO
    
    public Projeto salvarProjeto(ArrayList<Object> atributos)
    {
        Projeto p = new Projeto();
            
        p.setNome((String) atributos.get(0));
        p.setDataInicio((Calendar) atributos.get(1));
        p.setDataFim((Calendar) atributos.get(2));
        p.setTipo((TipoProjeto) atributos.get(3));
        p.setPrioridade((Prioridade) atributos.get(4));
        //TODO calcular status do projeto baseado nas datas
        p.setStatus(StatusProjeto.NAO_INICIADO);
        
        p.setGerente((Colaborador) atributos.get(5));
        
        try
        {
            p = (Projeto) apDaoProjeto.salvar(p);
        }
        catch (Exception ex)
        {
            Logger.getLogger(AplControleInterno.class.getName()).log(Level.SEVERE, null, ex); //TODO por que AplControleInterno??
        }

        return p;
    }

    public Projeto alterarProjeto(Projeto c)
    {
        try
        {
            return (Projeto) apDaoProjeto.salvar(c);
        }
        catch (Exception ex)
        {
            Logger.getLogger(AplControleInterno.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;
    }

    public boolean apagarProjeto(Projeto p)
    {
        try
        {
            //TODO fazer validacao antes
            apDaoProjeto.excluir(p);
        }
        catch (Exception ex)
        {
            Logger.getLogger(AplControleInterno.class.getName()).log(Level.SEVERE, null, ex);
        }

        return true;
    }

    public List<Projeto> obterProjetos()
    {
        try
        {
            return (List<Projeto>) apDaoProjeto.obter(Projeto.class);
        }
        catch (Exception ex)
        {
            Logger.getLogger(AplControleInterno.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;
    }
    
    //CATEGORIA
    
    public CategoriaTipo salvarCategoria(Map atributos)
    {
        CategoriaTipo c = new CategoriaTipo();
            
        c.setNome((String) atributos.get("nome"));
        
        try
        {
            c = (CategoriaTipo) apDaoCategoriaTipo.salvar(c);
        }
        catch (Exception ex)
        {
            Logger.getLogger(AplControleInterno.class.getName()).log(Level.SEVERE, null, ex); //TODO por que AplControleInterno??
        }

        return c;
    }

    public CategoriaTipo alterarCategoria(CategoriaTipo c)
    {
        try
        {
            return (CategoriaTipo) apDaoCategoriaTipo.salvar(c);
        }
        catch (Exception ex)
        {
            Logger.getLogger(AplControleInterno.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;
    }

    public boolean apagarCategoria(CategoriaTipo c)
    {
        try
        {
            //TODO fazer validacao antes
            apDaoCategoriaTipo.excluir(c);
        }
        catch (Exception ex)
        {
            Logger.getLogger(AplControleInterno.class.getName()).log(Level.SEVERE, null, ex);
        }

        return true;
    }
    
    //TIPO
    
    public TipoAtividade salvarTipo(Map atributos)
    {
        TipoAtividade t = new TipoAtividade();
            
        t.setNome((String) atributos.get("nome"));
        t.setDescricao((String) atributos.get("descricao"));
        t.setTipoPai((TipoAtividade) atributos.get("tipoPai"));
        t.setCategoria((CategoriaTipo) atributos.get("categoria"));
        
        try
        {
            t = (TipoAtividade) apDaoTipoAtividade.salvar(t);
        }
        catch (Exception ex)
        {
            Logger.getLogger(AplControleInterno.class.getName()).log(Level.SEVERE, null, ex); //TODO por que AplControleInterno??
        }

        return t;
    }
    
    public TipoAtividade alterarTipo(TipoAtividade t)
    {
        try
        {
            return (TipoAtividade) apDaoTipoAtividade.salvar(t);
        }
        catch (Exception ex)
        {
            Logger.getLogger(AplControleInterno.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;
    }

    public boolean apagarTipo(TipoAtividade t)
    {
        try
        {
            //TODO fazer validacao antes
            apDaoTipoAtividade.excluir(t);
        }
        catch (Exception ex)
        {
            Logger.getLogger(AplControleInterno.class.getName()).log(Level.SEVERE, null, ex);
        }

        return true;
    }
    
    public List<TipoAtividade> obterTipos()
    {
        try
        {
            return (List<TipoAtividade>) apDaoTipoAtividade.obter(TipoAtividade.class);
        }
        catch (Exception ex)
        {
            Logger.getLogger(AplControleInterno.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;
    }
    
    public List<TipoAtividade> obterTipos(CategoriaTipo ct)
    {
        try
        {
            return ((TipoAtividadeDAOJPA) apDaoTipoAtividade).obter(ct);
        }
        catch (Exception ex)
        {
            Logger.getLogger(AplControleInterno.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;
    }
    
    public List<TipoAtividade> obterFilhas(TipoAtividade t)
    {
        try
        {
            return ((TipoAtividadeDAOJPA) apDaoTipoAtividade).obterFilhas(t);
        }
        catch (Exception ex)
        {
            Logger.getLogger(AplControleInterno.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;
    }
    
    public void trocaPai(TipoAtividade tipo, TipoAtividade novoPai)
    {
        tipo.setTipoPai(novoPai);
        //this.alterarAtividade(atividade, atividade.getAlocados()); //TODO o pai interfere nos alocados??
        this.alterarTipo(tipo);
    }
    
    //CATEGORIA
    
    public List<CategoriaTipo> obterCategorias()
    {
        try
        {
            return (List<CategoriaTipo>) apDaoCategoriaTipo.obter(CategoriaTipo.class);
        }
        catch (Exception ex)
        {
            Logger.getLogger(AplControleInterno.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;
    }
}
